
import javax.swing.*;
import java.awt.image.*;
import java.awt.event.*;
import java.awt.*;

//public class GamePanel extends JPanel implements Runnable
public class GamePanel extends JPanel implements Runnable 
{
    
  private static final int PWIDTH = 384;   // size of panel
  private static final int PHEIGHT = 384; 
  // off-screen rendering
  private Graphics dbg; 
  private Image dbImage = null;
  Thread         GameLoop;
  Level          level;
  long			 thisTime; // 
  long			 lastTime; // Last time in miliseconds
  boolean		 gameRunning = true; // Game is running
  
  public void run()
  /* The frames of the animation are drawn inside the while loop. */
  {

      while( gameRunning ){
          lastTime = System.nanoTime()/1000L;		// Get Last nanosecond time
          // Attempt to create a Graphics 
          if (dbImage == null)
        	  InitGraphics();

          if( dbg != null ){

              thisTime = (System.nanoTime()/1000L);		// Get Last nanosecond time
              long deltaTime = thisTime - lastTime;
              if( deltaTime > 30)
            	  deltaTime = 1;
              try{
            	  Thread.sleep( 30 - deltaTime  );  // Sleep for 30ms
              }
              catch(InterruptedException ex){}

              lastTime = System.nanoTime()/1000L;
              
              
              level.Update(30);
              level.DrawScene(dbg); // Paint screen
              try {
                  Graphics g;
                  g = this.getGraphics();
                  if ((g != null) && (dbImage != null))
                      g.drawImage(dbImage, 0, 0, null);
                  // Sync the display on some systems.
                  // (on Linux, this fixes event queue problems)
                  Toolkit.getDefaultToolkit().sync();

                  g.dispose();
              }
              catch (Exception e)
              { System.out.println("Graphics context error: " + e);  }
              
          }
      } // end of run()
  } // end of run()
  
    public GamePanel()
    {
        setDoubleBuffered(false);
        setBackground(Color.black);
        setPreferredSize( new Dimension(PWIDTH, PHEIGHT));

        setFocusable(true);
        requestFocus();    // the JPanel now has focus, so receives key events
        
        
        addKeyListener( new KeyAdapter() {
            public void keyPressed(KeyEvent e) {  processKey(e, true);  }
            public void keyReleased(KeyEvent e) { processKey(e, false);  }
        });

        level = new Level();

        GameLoop = new Thread(this);
        GameLoop.start();
    }

    private void processKey(KeyEvent e, boolean pressed)
    // handles termination and game-play keys
    {
        int keyCode = e.getKeyCode();

        if (keyCode == KeyEvent.VK_LEFT){
            if( pressed )
                level.LeftStart();
            else
                level.LeftStop();
      }else if (keyCode == KeyEvent.VK_RIGHT){
          if( pressed )
              level.RightStart();
          else
              level.RightStop();
      }else if (keyCode == KeyEvent.VK_SPACE){
          if( pressed )
              level.Jump();
      }
    }  // end of processKey()
    void TurnOffGame(){
    	gameRunning = false;
    }
    
    void InitGraphics(){
    	dbImage = createImage(PWIDTH, PHEIGHT);
        if (dbImage != null) 
        	dbg = dbImage.getGraphics();
        else
            try{
                    Thread.sleep(1000L);  // nano -> ms
            }
            catch(InterruptedException ex){}
    }

}  // end of GamePanel class

